package cn.faifai.tagapi.service;

import cn.faifai.framework.jna.faifaiKernel32;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.*;
import com.sun.jna.ptr.IntByReference;

import java.io.IOException;

public class UsnJournalReader {
    public static void main(String[] args) throws IOException {
        // 打开卷设备
        WinNT.HANDLE hVolume = faifaiKernel32.INSTANCE.CreateFileA(
                "\\\\.\\D:", // 替换为目标卷
                new WinNT.DWORD(WinNT.GENERIC_READ | WinNT.GENERIC_WRITE), // GENERIC_READ | GENERIC_WRITE
                new WinNT.DWORD(WinNT.FILE_SHARE_READ | WinNT.FILE_SHARE_WRITE | WinNT.FILE_SHARE_DELETE), // FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE
                null, new WinNT.DWORD(WinNT.OPEN_EXISTING),
                new WinNT.DWORD(WinNT.FILE_FLAG_BACKUP_SEMANTICS), // FILE_FLAG_BACKUP_SEMANTICS
                null);

        if (!hVolume.equals(WinBase.INVALID_HANDLE_VALUE)) {
            try {
                // 这里应该准备READ_USN_JOURNAL_DATA_V0结构体，并调用DeviceIoControl
                // 示例简化了这部分内容，具体实现需根据需求调整

                IntByReference dwBytesReturned = new IntByReference(0);

                // DeviceIoControl(hVolume, FSCTL_READ_USN_JOURNAL, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped);
                // 准备一个足够大的输出缓冲区来接收USN日志数据
                byte[] outBuffer = new byte[65536]; // 例如64KB

                boolean result = Kernel32.INSTANCE.DeviceIoControl(
                        hVolume,
                        0x000900EB, // FSCTL_READ_USN_JOURNAL
                        null, 65536, // 对于此操作，可以没有输入缓冲区
                        null, 65536, // 输出缓冲区及其大小
                        dwBytesReturned,
                        new Pointer(1024)); // 不使用重叠结构

                if (result) {
                    System.out.println("成功读取USN日志");
                } else {
                    System.out.println("读取USN日志失败");
                    throw new IOException("Failed to open file. Error code: " + Native.getLastError());
                }
            } finally {
                Kernel32.INSTANCE.CloseHandle(hVolume);
            }
        }else {
            throw new IOException("Failed to open file. Error code: " + Native.getLastError());
        }
    }
}
